package rs.udd.service.document.query;

import java.util.StringTokenizer;

import org.apache.commons.lang3.StringUtils;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.FuzzyQuery;
import org.apache.lucene.search.PhraseQuery;
import org.apache.lucene.search.PrefixQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.util.Version;

import rs.udd.constants.GeneralConstants;
import rs.udd.service.document.analyzer.SerbianAnalyzer;

public class QueryBuilder {

	private static final Version matchVersion = Version.LUCENE_4_9;
	private static SerbianAnalyzer analyzer = new SerbianAnalyzer(matchVersion);
	private static int maxEdits = 1;

	public static int getMaxEdits() {
		return maxEdits;
	}

	public static void setMaxEdits(int maxEdits) {
		QueryBuilder.maxEdits = maxEdits;
	}

	public static Query buildQuery(GeneralConstants.SearchType searchType, String field, String value) throws IllegalArgumentException,
			ParseException {
		
		QueryParser parser = new QueryParser(matchVersion, field, analyzer);
		String errorMessage = "";
		if (StringUtils.isEmpty(field)) {
			errorMessage += "Field not specified";
		}
		if (value == null) {
			if (!errorMessage.equals(""))
				errorMessage += "\n";
			errorMessage += "Value not specified";
		}
		if (!errorMessage.equals("")) {
			throw new IllegalArgumentException(errorMessage);
		}

		Term term = new Term(field, value.trim());
		Query query = null;
		if (searchType.equals(GeneralConstants.SearchType.Regular)) {
			query = new TermQuery(term);
		} else if (searchType.equals(GeneralConstants.SearchType.Fuzzy)) {
			query = new FuzzyQuery(term, maxEdits);
		} else if (searchType.equals(GeneralConstants.SearchType.Prefix)) {
			query = new PrefixQuery(term);
		} else {
			StringTokenizer st = new StringTokenizer(value.trim());
			PhraseQuery pq = new PhraseQuery();
			while (st.hasMoreTokens()) {
				pq.add(new Term(field, st.nextToken()));
			}
			query = pq;
		}

		return parser.parse(query.toString(field));
	}

}
